package com.unnet.yjs.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.unnet.yjs.base.ContainerProperties;
import com.unnet.yjs.entity.Rescource;
import com.unnet.yjs.service.ResourceService;
import com.unnet.yjs.service.UploadService;
import com.unnet.yjs.util.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.util.*;

/**
 * Email: love1208tt@foxmail.com
 * Copyright (c)  2019. missbe
 *
 * @author lyg   19-7-1 下午9:55
 **/
@Service("myOssService")
public class MyOssServiceImpl implements UploadService {
    private static final Logger LOGGER = LoggerFactory.getLogger(MyOssServiceImpl.class);

    @Resource
    @Qualifier("containerProperties")
    private ContainerProperties containerProperties;
    @Resource
    private MinIoOssOperation minIoOssOperation;
    @Resource
    private ResourceService resourceService;

    /**
     * 文件上传方法
     *
     * @param file MultipartFile文件对象
     * @return 文件在云上的地址
     */
    @Override
    public String upload(MultipartFile file, Map<String, Object> map) throws IOException, NoSuchAlgorithmException {
        return upload(file, null, map);
    }

    /**
     * 文件上传方法
     *
     * @param file          MultipartFile文件对象
     * @param directoryName 文件目录名称
     * @return 文件在云上的地址
     */
    @Override
    public String upload(MultipartFile file, String directoryName, Map<String, Object> map) throws IOException, NoSuchAlgorithmException {
        ///计算文件hash值
        QETag tag = new QETag();
        String hash = tag.calcETag(file);

        String fileName;
        String isRename = (String) map.get("isRename");
        String areaId = (String) map.get("AREA_ID");
        ///判断文件是否重命名
        ///TODO 文件无后缀时会报越界异常
        if (Boolean.TRUE.equals(Boolean.valueOf(isRename))) {
            String originalName = file.getOriginalFilename();
            String extName = Objects.nonNull(originalName) ? originalName.substring(originalName.lastIndexOf(".")) : file.getContentType();
            fileName = hash + extName;
        } else {
            fileName = file.getOriginalFilename();
        }
        ////根据文件hash值和文件类型来查找是否存在文件
        EntityWrapper<Rescource> wrapper = new EntityWrapper<>();
        wrapper.eq("hash", hash);
        wrapper.eq("source", "myoss");
        wrapper.eq("is_rename", Boolean.valueOf(isRename));
        Rescource rescource = resourceService.selectOne(wrapper);
        if (rescource != null) {
            LOGGER.info("current oss file already save, web url is " + rescource.getWebUrl());
            return rescource.getWebUrl();
        }

        ///store the file
        long fileSize = file.getSize();
        boolean suc;
        ///mini io oss存储
        try {
            suc = minIoOssOperation.store(file.getInputStream(), fileSize, fileName);
        } catch (Exception e) {
            LOGGER.error("Minio对象存储上传出错,MSg:" + e.getLocalizedMessage());
            return "ERROR:" + "Minio对象存储上传出错,MSg:" + e.getLocalizedMessage();
        }
        if (!suc) {
            return "ERROR:" + "Minio对象存储上传出错.";
        }
        String webUrl;
        if ("video".equalsIgnoreCase(directoryName)) {
            ///对象存储直接用名称请求文件流-路径中转
            webUrl = "http://" + containerProperties.getFileServerContext() + "/api/v1/resource/file/video/" + fileName;
        } else {
            ///对象存储直接用名称请求文件流-路径中转
            webUrl = "http://" + containerProperties.getFileServerContext() + "/api/v1/resource/file/storage/" + fileName;
        }

        LOGGER.info("oss store file:" + file.getOriginalFilename() + " success. save file name:" + fileName);

        if (!webUrl.isEmpty()) {
            rescource = new Rescource();
            String originalFileName = file.getOriginalFilename();
            ////如果原文件名称为null，采用系统当前时间生成文件名称
            originalFileName = Objects.nonNull(originalFileName) ? originalFileName : "mills" + System.currentTimeMillis();
            rescource.setFileName(originalFileName);
            rescource.setFileSize(new java.text.DecimalFormat("#.##").format(file.getSize() / 1024) + "kb");
            rescource.setHash(hash);
            rescource.setFileType(file.getContentType());
            rescource.setWebUrl(webUrl);
            rescource.setSource("myoss");
            rescource.setAreaId(areaId);
            rescource.setOriginalNetUrl(webUrl);
            rescource.setRename(Boolean.valueOf(isRename));
            rescource.setRemarks(String.valueOf(map.get("remarks")));
            resourceService.insert(rescource);
        } else {
            LOGGER.info("store error,paas store no result.");
            webUrl = null;
        }

        return webUrl;
    }

    @Override
    public Boolean delete(List<String> fileNames) {
        return minIoOssOperation.remove(fileNames);
    }

    /**
     * 删除已经上传到云上的文件
     *
     * @param path 文件地址
     * @return 是否删除成功
     */
    @Override
    public Boolean delete(String path) {
        return minIoOssOperation.remove(Collections.singletonList(path));
    }

    /**
     * 上传网络文件
     *
     * @param url 网络文件的地址
     * @return 文件在云上的地址
     */
    @Override
    public String uploadNetFile(String url) throws IOException, NoSuchAlgorithmException {
        return null;
    }

    /**
     * 上传本地指定路径的图片
     *
     * @param localPath (指的是用户的)本地路径
     */
    @Override
    public String uploadLocalImg(String localPath) {
        return null;
    }

    /**
     * 上传base64格式的文件
     *
     * @param base64 文件的base64编码
     */
    @Override
    public String uploadBase64(String base64) {
        return null;
    }

}

